package jmine.tec.test.utils.xls;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import jmine.tec.utils.Tuple;
import jmine.tec.utils.UnmodifiableTuple;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;

/**
 * Interface para facilitar uso de excel.
 * 
 * @author bolha
 */
public class XLSWrapper {
    /**
     * Representa a planilha em si.
     */
    private HSSFWorkbook wb;

    /**
     * Construtor.
     * 
     * @param resource recurso para o xls
     * @throws IOException se nao conseguir ler o recurso
     */
    public XLSWrapper(final InputStream resource) throws IOException {
        POIFSFileSystem fs = new POIFSFileSystem(resource);
        this.wb = new HSSFWorkbook(fs);
    }

    /**
     * Carrega uma serie a partir de uma planilha excel. Basta especificar o nome da serie, que deve estar em uma worksheet com este nome,
     * dizer quais sao as colunas contendo a data e o valor da serie.
     * 
     * @param nome nome da serie que sera carregada, deve ser o nome de uma worksheet
     * @param dataCol coluna com as datas que serao carregadas
     * @param valueCol coluna com os valores que serao carregados
     * @return lista com a serie
     * @throws IOException se nao conseguir ler o recurso
     */
    public List<Tuple<Date, Double>> carregaSerie(final String nome, final int dataCol, final int valueCol) throws IOException {

        HSSFSheet sheet = this.wb.getSheet(nome);

        // percorro as linhas
        List<Tuple<Date, Double>> points = new ArrayList<Tuple<Date, Double>>();

        for (Iterator<Row> rowIter = sheet.rowIterator(); rowIter.hasNext();) {
            Row row = rowIter.next();

            // obtenho a data
            Cell dateCell = row.getCell(dataCol);
            Date date = dateCell.getDateCellValue();

            // obtenho o valor
            Cell valueCell = row.getCell(valueCol);
            double value = valueCell.getNumericCellValue();

            Tuple<Date, Double> t = UnmodifiableTuple.newTuple(date, value);

            points.add(t);
        }

        return points;
    }

    /**
     * @param nome nome da serie que sera carregada, deve ser o nome de uma worksheet
     * @param valueCol coluna com os valores que serao carregados
     * @return lista com os valores da serie
     */
    public List<Double> carregaSerieValores(final String nome, final int valueCol) {
        List<Double> points = new ArrayList<Double>();

        HSSFSheet sheet = this.wb.getSheet(nome);

        for (Iterator<Row> rowIter = sheet.rowIterator(); rowIter.hasNext();) {
            Row row = rowIter.next();

            // obtenho o valor
            Cell valueCell = row.getCell(valueCol);
            double value = valueCell.getNumericCellValue();

            points.add(new Double(value));
        }

        return points;
    }
}
